home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TUTORC.ZIP / TUT8.C < prev    next >
C/C++ Source or Header  |  1994-10-30  |  10KB  |  285 lines

  1. /* 
  2.   tut8.c
  3.   10/30/94
  4.   from tutprog8.pas
  5.   Adapted from Denthor's tutprog8.pas
  6.   Translated into C, from Denthor's VGA Trainer, by
  7.   Steve Pinault, scp@ohm.att.com
  8.   Compiled with Microsoft Visual C++ 1.5 (Microsoft C 8.0)
  9.   To compile:
  10.   First compile the subroutines in tutsubs.c with the batch file 
  11.   cltutsub.bat
  12.   Then compile any of the tutor programs with the batch file
  13.   cltut.bat
  14.   Example: C:>cltutsub
  15.            C:>cltut tut8.c
  16.            to compile this program.
  17. */
  18.  
  19. #include "tutheadr.h"
  20. #define MaxLines  12
  21.  
  22. int Obj[MaxLines][2][3]= {
  23.         {{-10,-10,-10},{10,-10,-10}},{{-10,-10,-10},{-10,10,-10}},
  24.         {{-10,10,-10},{10,10,-10}},{{10,-10,-10},{10,10,-10}},
  25.         {{-10,-10,10},{10,-10,10}},{{-10,-10,10},{-10,10,10}},
  26.         {{-10,10,10},{10,10,10}},{{10,-10,10},{10,10,10}},
  27.         {{-10,-10,10},{-10,-10,-10}},{{-10,10,10},{-10,10,-10}},
  28.         {{10,10,10},{10,10,-10}},{{10,-10,10},{10,-10,-10}}
  29.         }; // { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
  30.            // { (X2,Y2,Z2) ... for the two ends of a line }
  31.  
  32.  
  33. struct Point Lines[MaxLines][2];
  34. struct Point translated[MaxLines][2];
  35. int xoff,yoff,zoff;
  36. float lookup[360][2];
  37.  
  38. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  39. // Procedure SetUpPoints;
  40. //   { This sets the basic offsets of the object, creates the lookup table and
  41. //     moves the object from a constant to a variable }
  42. void SetUpPoints()
  43. {
  44.   int loop1;
  45.   xoff=160;
  46.   yoff=100;
  47.   zoff=-256;
  48.   for(loop1=0;loop1<360;loop1++)
  49.   {
  50.     lookup [loop1][0]=(float)sin ((double)rad ((float)loop1));
  51.     lookup [loop1][1]=(float)cos ((double)rad ((float)loop1));
  52.   }
  53.   for(loop1=0;loop1<MaxLines;loop1++)
  54.   {
  55.     Lines [loop1][0].x=Obj [loop1][0][0];
  56.     Lines [loop1][0].y=Obj [loop1][0][1];
  57.     Lines [loop1][0].z=Obj [loop1][0][2];
  58.     Lines [loop1][1].x=Obj [loop1][1][0];
  59.     Lines [loop1][1].y=Obj [loop1][1][1];
  60.     Lines [loop1][1].z=Obj [loop1][1][2];
  61.   }
  62. }
  63.  
  64. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  65. // Procedure DrawLogo;
  66. //   { This draws 'ASPHYXIA' at the top of the screen in little balls }
  67. void DrawLogo()
  68. {
  69.   char ball[5][5]=
  70.          {{0,1,1,1,0},
  71.           {1,4,3,2,1},
  72.           {1,3,3,2,1},
  73.           {1,2,2,2,1},
  74.           {0,1,1,1,0}};
  75.  
  76.   char Logo[5][32] = {
  77.   " O  OOO OOO O O O O O O OOO  O ",
  78.   "O O O   O O O O O O O O  O  O O",
  79.   "OOO OOO OOO OOO  O   O   O  OOO",
  80.   "O O   O O   O O  O  O O  O  O O",
  81.   "O O OOO O   O O  O  O O OOO O O" };
  82.   int  loop1,loop2,loop3,loop4;
  83.   Pal (13,0,63,0);
  84.   Pal (1,0,0,40);
  85.   Pal (2,0,0,45);
  86.   Pal (3,0,0,50);
  87.   Pal (4,0,0,60);
  88.   for(loop1=0;loop1<5;loop1++)
  89.     for(loop2=0;loop2<31;loop2++)
  90.       if(Logo[loop1][loop2]=='O')
  91.         for(loop3=0;loop3<5;loop3++)
  92.           for(loop4=0;loop4<5;loop4++)
  93.             PutPixel (loop2*10+loop3,loop1*4+loop4,ball[loop3][loop4],Vaddr);
  94. }
  95.  
  96. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  97. // Procedure RotatePoints (X,Y,Z:Integer);
  98. //   { This rotates object lines by X,Y and Z; then places the result in
  99. //     TRANSLATED }
  100. // rotate about x: newy = cos*y-sin*z (cos*cos-sin*sin)
  101. //                 newz = sin*y+cos*z (sin*cos+cos*sin)
  102. //           i.e:  newy+i*newz=e^(i*theta)*(y+i*z) (theta=int x)
  103. //                            =(cos+i*sin)*(y+i*z)
  104. // translated[loop1][0] and translated[loop1][1] are the two endpoints
  105. // of line segment loop1.
  106. //
  107. void RotatePoints(int x, int y, int z)
  108. {
  109.   int loop1;
  110.   struct Point temp;
  111.   for(loop1=0;loop1<MaxLines;loop1++)
  112.   {
  113. temp.x=Lines[loop1][0].x;
  114. temp.y=lookup[x][1]*Lines[loop1][0].y - lookup[x][0]*Lines[loop1][0].z;
  115. temp.z=lookup[x][0]*Lines[loop1][0].y + lookup[x][1]*Lines[loop1][0].z;
  116. translated[loop1][0]=temp;
  117.  
  118. temp.x=lookup[y][1]*translated[loop1][0].x-lookup[y][0]*translated[loop1][0].y;
  119. temp.y=lookup[y][0]*translated[loop1][0].x+lookup[y][1]*translated[loop1][0].y;
  120. temp.z=translated[loop1][0].z;
  121. translated[loop1][0]=temp;
  122.  
  123. temp.z=lookup[z][1]*translated[loop1][0].z-lookup[z][0]*translated[loop1][0].x;
  124. temp.x=lookup[z][0]*translated[loop1][0].z+lookup[z][1]*translated[loop1][0].x;
  125. temp.y=translated[loop1][0].y;
  126. translated[loop1][0]=temp;
  127.  
  128. temp.x=Lines[loop1][1].x;
  129. temp.y=lookup[x][1]*Lines[loop1][1].y-lookup[x][0]*Lines[loop1][1].z;
  130. temp.z=lookup[x][0]*Lines[loop1][1].y+lookup[x][1]*Lines[loop1][1].z;
  131. translated[loop1][1]=temp;
  132.  
  133. temp.x=lookup[y][1]*translated[loop1][1].x-lookup[y][0]*translated[loop1][1].y;
  134. temp.y=lookup[y][0]*translated[loop1][1].x+lookup[y][1]*translated[loop1][1].y;
  135. temp.z=translated[loop1][1].z;
  136. translated[loop1][1]=temp;
  137.  
  138. temp.z=lookup[z][1]*translated[loop1][1].z-lookup[z][0]*translated[loop1][1].x;
  139. temp.x=lookup[z][0]*translated[loop1][1].z+lookup[z][1]*translated[loop1][1].x;
  140. temp.y=translated[loop1][1].y;
  141. translated[loop1][1]=temp;
  142.   }
  143. }
  144.  
  145.  
  146.  
  147. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  148. // Procedure DrawPoints;
  149. //   { This draws the translated object to the virtual screen }
  150. void DrawPoints()
  151. {
  152.   int loop1;
  153.   int nx,ny,nx2,ny2;
  154.   int temp1,temp2;
  155.   for(loop1=0;loop1<MaxLines;loop1++)
  156.   {
  157.     temp1=round (translated[loop1][0].z+zoff);
  158.     temp2=round (translated[loop1][1].z+zoff);
  159.     if((temp1<0)&&(temp2<0))
  160.     {
  161.       nx  =round (256*translated[loop1][0].x) / temp1 + xoff;
  162.       ny  =round (256*translated[loop1][0].y) / temp1 + yoff;
  163.       nx2 =round (256*translated[loop1][1].x) / temp2 + xoff;
  164.       ny2 =round (256*translated[loop1][1].y) / temp2 + yoff;
  165.       if((nx > 0)  && (nx < 320)  && (ny > 25)  && (ny < 200) && 
  166.          (nx2> 0)  && (nx2< 320)  && (ny2> 25)  && (ny2< 200)) 
  167.            Line2 (nx,ny,nx2,ny2,13,Vaddr);
  168.     }
  169.   }
  170. }
  171.  
  172. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  173. // Procedure ClearPoints;
  174. //   { This clears the translated object from the virtual screen ... believe it
  175. //     or not, this is faster then a straight "cls (vaddr,0)" }
  176. void ClearPoints()
  177. {
  178.   int loop1;
  179.   int nx,ny,nx2,ny2;
  180.   int temp1,temp2;
  181.   for(loop1=0;loop1<MaxLines;loop1++)
  182.   {
  183.     temp1=round (translated[loop1][0].z+zoff);
  184.     temp2=round (translated[loop1][1].z+zoff);
  185.     if((temp1<0)&&(temp2<0))
  186.     {
  187.       nx  =round (256*translated[loop1][0].x) / temp1 + xoff;
  188.       ny  =round (256*translated[loop1][0].y) / temp1 + yoff;
  189.       nx2 =round (256*translated[loop1][1].x) / temp2 + xoff;
  190.       ny2 =round (256*translated[loop1][1].y) / temp2 + yoff;
  191.       if((nx > 0) &&  (nx < 320) &&  (ny > 25) &&  (ny < 200) && 
  192.          (nx2> 0) &&  (nx2< 320) &&  (ny2> 25) &&  (ny2< 200))
  193.            Line2 (nx,ny,nx2,ny2,0,Vaddr);
  194.     }
  195.   }
  196. }
  197.  
  198.  
  199. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  200. // Procedure MoveAround;
  201. //   { This is the main display procedure. Firstly it brings the object towards
  202. //     the viewer by increasing the Zoff, then passes control to the user }
  203. void MoveAround()
  204. {
  205.   int deg,loop1;
  206.   char ch;
  207.   deg=0;
  208.   ch=0x0;
  209.   Cls(0,Vaddr);
  210.   DrawLogo();
  211.   for(loop1=-256;loop1<=-40;loop1++)
  212.   {
  213.     zoff=loop1*2;
  214.     RotatePoints(deg,deg,deg);
  215.     DrawPoints();
  216.     WaitRetrace();
  217.     Flip2(Vaddr,VGA);
  218.     ClearPoints();
  219.     deg++; // mod 360;
  220.     if(deg==360)deg=0;
  221.   }
  222.  
  223.   while(ch!=0x1b)  // escape
  224.   {
  225.     if(_bios_keybrd(_KEYBRD_READY))
  226.     {
  227.       ch=(getch()&0x00ff);
  228.       if(ch==0x71)break; // 'q'
  229.       if(ch==0x51)break; // 'Q'
  230.       if(ch==0x1b)break; // ESC
  231.       if(ch=='Z')zoff+=5;
  232.       if(ch=='z')zoff-=5;
  233.       if(ch=='X')xoff+=5;
  234.       if(ch=='x')xoff-=5;
  235.       if(ch=='Y')yoff+=5;
  236.       if(ch=='y')yoff-=5;
  237.     }
  238.     DrawPoints();
  239.     WaitRetrace();
  240.     Flip2(Vaddr,VGA);
  241.     ClearPoints();
  242.     RotatePoints (deg,deg,deg);
  243.     deg++; // mod 360;
  244.     if(deg==360)deg=0;
  245.   }
  246. }
  247.  
  248. void main()
  249. {
  250.   SetUpVirtual();
  251.   printf("  Greetings and salutations! Hope you had a great Christmas and New\n");
  252.   printf("  year! ;-) ... Anyway, this tutorial is on 3-D, so this is what is\n");
  253.   printf("  going to happen ... a wireframe square will come towards you.\n");
  254.   printf("  When it gets close, you get control. z and Z control the Z\n");
  255.   printf("  movement, x and X control the X movement, and y and Y\n");
  256.   printf("  control the Y movement. I have not included rotation control, but\n");
  257.   printf("  it should be easy enough to put in yourself ... if you have any\n");
  258.   printf("  hassles, leave me mail.\n");
  259.   printf(" \n");
  260.   printf("  Read the main text file for ideas on improving this code ... and\n");
  261.   printf("  welcome to the world of 3-D!\n");
  262.   printf("  Hit any key to continue: ");
  263.   getch();
  264.   SetMCGA();
  265.   SetUpPoints();
  266.   MoveAround();
  267.   SetText();
  268.   printf("  All done. This concludes the eigth sample program in the ASPHYXIA\n");
  269.   printf("  Training series. You may reach DENTHOR under the names of GRANT\n");
  270.   printf("  SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid\n");
  271.   printf("  Connectix BBS user, and occasionally read RSAProg.\n");
  272.   printf("  For discussion purposes, I am also the moderator of the Programming\n");
  273.   printf("  newsgroup on the For Your Eyes Only BBS.\n");
  274.   printf("  The numbers are available in the main text. You may also write to me at:\n");
  275.   printf("               Grant Smith\n");
  276.   printf("               P.O. Box 270\n");
  277.   printf("               Kloof\n");
  278.   printf("               3640\n");
  279.   printf("  I hope to hear from you soon!\n");
  280.   printf("  \n");
  281.   printf("  \n");
  282.   printf("  \n");
  283.   printf(" Translated into C by Steve Pinault,\n scp@ohm.att.com\n\n");
  284. }
  285.